// 请求队列管理器
// @/utils/http/RequestQueue.ts

interface QueueItem<T = any> {
  id: string
  priority: number
  execute: () => Promise<T>
  resolve: (value: T) => void
  reject: (reason: any) => void
  timestamp: number
  timeout?: number
}

export class RequestQueue {
  private queue: QueueItem[] = []
  private running: Map<string, QueueItem> = new Map()
  private maxConcurrent: number
  private idCounter: number = 0
  private paused: boolean = false

  constructor(maxConcurrent: number = 6) {
    this.maxConcurrent = maxConcurrent
  }

  // 添加请求到队列
  async add<T = any>(
    execute: () => Promise<T>,
    options: {
      priority?: number
      timeout?: number
    } = {}
  ): Promise<T> {
    return new Promise((resolve, reject) => {
      const item: QueueItem<T> = {
        id: this.generateId(),
        priority: options.priority || 0,
        execute,
        resolve,
        reject,
        timestamp: Date.now(),
        timeout: options.timeout
      }

      this.enqueue(item)
      this.process()
    })
  }

  // 添加到队列
  private enqueue(item: QueueItem): void {
    // 按优先级插入
    const index = this.queue.findIndex(q => q.priority < item.priority)
    if (index === -1) {
      this.queue.push(item)
    } else {
      this.queue.splice(index, 0, item)
    }
  }

  // 处理队列
  private async process(): Promise<void> {
    if (this.paused) {
      return
    }

    while (this.running.size < this.maxConcurrent && this.queue.length > 0) {
      const item = this.queue.shift()
      if (!item) break

      this.running.set(item.id, item)
      this.executeItem(item)
    }
  }

  // 执行队列项
  private async executeItem(item: QueueItem): Promise<void> {
    let timeoutId: number | undefined

    try {
      // 设置超时
      const timeoutPromise = new Promise((_, reject) => {
        if (item.timeout) {
          timeoutId = setTimeout(() => {
            reject(new Error(`请求超时 (${item.timeout}ms)`))
          }, item.timeout) as unknown as number
        }
      })

      // 执行请求
      const result = await Promise.race([
        item.execute(),
        timeoutPromise
      ])

      item.resolve(result)
    } catch (error) {
      item.reject(error)
    } finally {
      // 清理
      if (timeoutId) {
        clearTimeout(timeoutId)
      }
      this.running.delete(item.id)
      
      // 继续处理队列
      this.process()
    }
  }

  // 暂停队列
  pause(): void {
    this.paused = true
  }

  // 恢复队列
  resume(): void {
    this.paused = false
    this.process()
  }

  // 清空队列
  clear(): void {
    // 拒绝所有等待中的请求
    this.queue.forEach(item => {
      item.reject(new Error('队列已清空'))
    })
    this.queue = []
  }

  // 获取队列状态
  getStatus(): {
    pending: number
    running: number
    total: number
    paused: boolean
  } {
    return {
      pending: this.queue.length,
      running: this.running.size,
      total: this.queue.length + this.running.size,
      paused: this.paused
    }
  }

  // 生成唯一 ID
  private generateId(): string {
    return `${Date.now()}-${++this.idCounter}`
  }

  // 设置最大并发数
  setMaxConcurrent(max: number): void {
    this.maxConcurrent = max
    this.process()
  }

  // 获取等待时间估算
  getEstimatedWaitTime(priority: number = 0): number {
    const position = this.queue.filter(item => item.priority >= priority).length
    const avgProcessTime = 3000 // 假设平均处理时间 3 秒
    
    return Math.ceil(position / this.maxConcurrent) * avgProcessTime
  }

  // 按优先级清理队列
  clearByPriority(priority: number): number {
    const itemsToRemove = this.queue.filter(item => item.priority <= priority)
    
    itemsToRemove.forEach(item => {
      item.reject(new Error('请求已被清理'))
    })

    this.queue = this.queue.filter(item => item.priority > priority)
    
    return itemsToRemove.length
  }

  // 获取队列详情
  getQueueDetails(): Array<{
    id: string
    priority: number
    waitTime: number
  }> {
    const now = Date.now()
    
    return this.queue.map(item => ({
      id: item.id,
      priority: item.priority,
      waitTime: now - item.timestamp
    }))
  }
} 